<template>
  <div class="app-container">
    <el-row>
      <!-- 搜索区域 -->
      <el-card style="margin:0 0 5px 5px" v-show="showSearch">
        <el-form ref="queryForm" :inline="true" :model="queryData">
          <el-form-item label="数据源" prop="Q_dbKey_S_EQ">
            <el-select v-model="queryData.Q_dbKey_S_EQ" filterable reserve-keyword clearable>
              <el-option
                v-for="item in optionOfDbSource"
                :key="item.id"
                :label="item.text"
                :value="item.id"
              />
            </el-select>
          </el-form-item>
          <el-form-item label="表单名称" prop="Q_tableName_S_LK">
            <el-input v-model="queryData.Q_tableName_S_LK" placeholder="表单名称" />
          </el-form-item>
          <el-form-item label="表单描述" prop="Q_tableComment_S_LK">
            <el-input v-model="queryData.Q_tableComment_S_LK" placeholder="表单描述" />
          </el-form-item>
          <el-form-item>
            <el-button class="filter-item m-l-20" type="primary" round icon="el-icon-search" @click="handleFilter">
              搜索
            </el-button>
          </el-form-item>
        </el-form>
      </el-card>

      <!-- table区域 -->
      <el-card class="m-l-5">
        <el-row :gutter="10" class="m-b-5">
          <el-col :span="1.5">
            <el-button v-permission="['tool:gen:init']" size="mini" plain type="success" icon="el-icon-plus" @click="handleInitTable()">
              基于DB导入
            </el-button>
          </el-col>
          <el-col :span="1.5">
            <el-button v-permission="['tool:gen:export']" size="mini" plain type="primary" icon="el-icon-plus" @click="handleGen()">
              批量生成代码
            </el-button>
          </el-col>
          <table-toolbar :showSearch.sync="showSearch" @refresh="getTableData" />
        </el-row>
        <el-table
          ref="queryTable"
          v-loading="tableLoading"
          row-key="tableId"
          :data="tableData"
          element-loading-text="加载中"
          border
          fit
          highlight-current-row
          height="100px"
          v-el-height-adaptive-table="{bottomOffset: 110}"
          show-overflow-tooltip
          @selection-change="handleSelectionChange"
        >
          <el-table-column type="selection" width="40" />
          <el-table-column align="center" label="数据源" prop="dbKey" sortable show-overflow-tooltip />
          <el-table-column align="center" label="表名称" prop="tableName" width="200" show-overflow-tooltip>
            <template slot-scope="scope">
              <span style="cursor: pointer" @click="handleColumnEdit(scope.row.tableId, scope.row.tableName)">{{ scope.row.tableName }}</span>
            </template>
          </el-table-column>
          <el-table-column align="center" label="类名称" prop="className" sortable show-overflow-tooltip />
          <el-table-column align="center" label="表描述" prop="tableComment" show-overflow-tooltip />
          <el-table-column align="center" label="操作" width="100" fixed="right">
            <template slot-scope="scope">
              <el-dropdown>
                <span class="el-dropdown-link">
                  选项<i class="el-icon-arrow-down el-icon--right" />
                </span>
                <el-dropdown-menu slot="dropdown">
                  <el-dropdown-item v-permission="['tool:gen:export']">
                    <el-link type="primary" @click="handlePreview(scope.row.tableId)"><i class="fa fa-eye" />预览</el-link>
                  </el-dropdown-item>
                  <el-dropdown-item v-permission="['tool:gen:edit']">
                    <el-link type="warning" @click="handleColumnEdit(scope.row.tableId, scope.row.tableName)"><i class="fa fa-pencil-square-o" />配置元数据规则</el-link>
                  </el-dropdown-item>
                  <el-dropdown-item v-permission="['tool:gen:export']">
                    <el-link @click="handleGenJava(scope.row.tableId, scope.row.tableName)"><i class="fa fa-download" />生成Java代码</el-link>
                  </el-dropdown-item>
                  <el-dropdown-item v-permission="['tool:gen:export']">
                    <el-link @click="handleGenHtml(scope.row.tableId, scope.row.tableName)"><i class="fa fa-download" />生成Html代码</el-link>
                  </el-dropdown-item>
                  <el-dropdown-item v-permission="['tool:gen:export']">
                    <el-link @click="handleGenVue(scope.row.tableId, scope.row.tableName)"><i class="fa fa-download" />生成Vue代码</el-link>
                  </el-dropdown-item>
                  <el-dropdown-item v-permission="['tool:gen:export']">
                    <el-link type="success" @click="handleGen(scope.row.tableId, scope.row.tableName)"><i class="fa fa-download" />生成所有代码</el-link>
                  </el-dropdown-item>
                </el-dropdown-menu>
              </el-dropdown>
            </template>
          </el-table-column>
        </el-table>

        <pagination v-show="tableQuery.total>0" :total="tableQuery.total" :page.sync="tableQuery.page" :limit.sync="tableQuery.limit" @pagination="getTableData" />
      </el-card>
    </el-row>

    <gen-table-import v-if="openImportDialog" ref="genTableImport" @confirm="handleFilter" />
    <gen-column-edit v-if="openEditDialog" ref="genColumnEdit" />

    <!-- 预览界面 -->
    <el-dialog title="预览" :visible.sync="preview.open" width="90%" top="5vh" append-to-body class="scrollbar">
      <el-row :gutter="10">
        <el-col :span="7">
          <el-tree
            :data="preview.fileTree"
            :expand-on-click-node="false"
            style="max-height: 65vh; overflow-y: scroll;"
            default-expand-all
            highlight-current
            @node-click="handleNodeClick"
          />
        </el-col>
        <el-col :span="17">
          <el-tabs v-model="preview.activeName">
            <el-tab-pane v-for="item in preview.data"
                         :label="item.path.substring(item.path.lastIndexOf('\\') + 1)"
                         :name="item.path"
                         :key="item.path">
              <el-link
                :underline="false"
                icon="el-icon-document-copy"
                v-clipboard:copy="item.code"
                v-clipboard:success="clipboardSuccess"
                style="float:right"
              >
                复制
              </el-link>
              <el-card>
                <pre><code class="hljs" style="max-height: calc(55vh - 10px); overflow-y: auto;" v-html="highlightedCode(item)"></code></pre>
              </el-card>
            </el-tab-pane>
          </el-tabs>
        </el-col>
      </el-row>
    </el-dialog>
  </div>
</template>

<script>
import { generatorTable, previewCode } from '@/api/tool/generator'
import { dbaseSelectData } from '@/api/tool/dbase'
import 'highlight.js/styles/github.css'
const hljs = require('highlight.js/lib/core')
hljs.registerLanguage('java', require('highlight.js/lib/languages/java'))
hljs.registerLanguage('xml', require('highlight.js/lib/languages/xml'))
hljs.registerLanguage('html', require('highlight.js/lib/languages/xml'))
hljs.registerLanguage('vue', require('highlight.js/lib/languages/xml'))
hljs.registerLanguage('javascript', require('highlight.js/lib/languages/javascript'))
hljs.registerLanguage('sql', require('highlight.js/lib/languages/sql'))
hljs.registerLanguage('typescript', require('highlight.js/lib/languages/typescript'))
import GenTableImport from './table/genTableImport'
import GenColumnEdit from './table/genColumnEdit'

export default {
  components: {
    GenTableImport,
    GenColumnEdit
  },
  computed: {
    fileSplit: {
      get() {
        return process.env.NODE_ENV === 'development' ? '\\' : '/'
      },
      set() {
        return ''
      }
    }
  },
  data() {
    return {
      showSearch: true,
      queryData: {
        Q_dbKey_S_EQ: undefined,
        Q_tableName_S_LK: undefined,
        Q_tableComment_S_LK: undefined
      },
      tableLoading: false,
      tableData: [],
      tableQuery: {
        page: 1,
        limit: 20,
        total: 0,
        sort: undefined,
        order: undefined
      },
      selectionData: [],
      optionOfDbSource: [],
      openImportDialog: false,
      openEditDialog: false,
      // 预览参数
      preview: {
        open: false,
        fileTree: [],
        data: {},
        activeName: ''
      }
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.init()
    })
  },
  methods: {
    init() {
      // 加载table数据
      this.getDbData()
      this.getTableData()
    },
    handleFilter() {
      this.tableQuery.page = 1
      this.getTableData()
    },
    handleClear() {
      this.$refs.queryForm.resetFields()
      this.getTableData()
    },
    getDbData() {
      dbaseSelectData().then(response => {
        this.optionOfDbSource =[...this.optionOfDbSource, ...response.param.data]
      }).catch(e => {})
    },
    getTableData() {
      const query = Object.assign(this.tableQuery, this.queryData)
      this.tableLoading = true
      generatorTable(query).then(response => {
        this.tableData = response.param.data
        this.tableQuery.total = response.param.recordsTotal
        this.tableLoading = false
        this.$refs.queryTable.bodyWrapper.scrollTop = 0
      }).catch(e => {
        this.tableLoading = false
      })
    },
    handleSelectionChange(val) {
      this.selectionData = val
    },
    handleInitTable() {
      this.openImportDialog = true
      this.$nextTick(() => {
        this.$refs.genTableImport.init()
      })
    },
    handlePreview(tableId) {
      previewCode(tableId).then(response => {
        this.preview.data = response.param
        let files = this.handleFiles(response.param)
        this.preview.fileTree = this.$api.buildTree(files, 'id', 'parentId', 'children', this.fileSplit)
        const activePath = response.param[0].path
        this.preview.activeName = activePath
        this.preview.open = true
      })
    },
    // 生成files目录
    handleFiles(datas) {
      let exists = {}
      let files = []

      for (const data of datas) {
        let paths = data.path.split(this.fileSplit)
        let fullPath = ''
        // 特殊处理 java 文件
        if (paths[paths.length - 1].indexOf('.java') >= 0) {
          let newPaths = []
          for (let i = 0; i < paths.length; i++) {
            let path = paths[i]
            if (path !== 'java') {
              newPaths.push(path)
              continue
            }
            newPaths.push(path)
            // 特殊处理中间的 package，进行合并
            let tmp = undefined
            while (i < paths.length) {
              path = paths[i + 1]
              if (path === 'controller'
                || path === 'service'
                || path === 'repository'
                || path === 'impl'
                || path === 'persistence'
                || path === 'model') {
                break
              }
              tmp = tmp ? tmp + '.' + path : path
              i++
            }
            if (tmp) {
              newPaths.push(tmp)
            }
          }
          paths = newPaths
        }

        for (let i = 0; i < paths.length; i++) {
          let oldFullPath = fullPath
          fullPath = fullPath.length === 0 ? paths[i] : fullPath.replaceAll('.', this.fileSplit) + this.fileSplit + paths[i]
          if (exists[fullPath]) {
            continue
          }
          exists[fullPath] = true
          files.push({
            id: fullPath,
            label: paths[i],
            parentId: oldFullPath || this.fileSplit
          })
        }
      }
      return files
    },
    handleNodeClick(data, node) {
      if (node && !node.isLeaf) {
        return false
      }
      this.preview.activeName = data.id.replaceAll('/', this.fileSplit)
    },
    highlightedCode(item) {
      let language = item.path.substring(item.path.lastIndexOf('.') + 1)
      const result = hljs.highlight(language, item.code || '', true)
      return result.value || '&nbsp;'
    },
    clipboardSuccess() {
      this.$modal.msgSuccess('复制成功')
    },
    handleGenJava(tableId, tableName) {
      const url = '/genCode?tableId=' + tableName + '&type=java'
      this.handleGen(tableId, tableName, url)
    },
    handleGenHtml(tableId, tableName) {
      const url = '/genCode?tableId=' + tableName + '&type=html'
      this.handleGen(tableId, tableName, url)
    },
    handleGenVue(tableId, tableName) {
      const url = '/genCode?tableId=' + tableName + '&type=vue'
      this.handleGen(tableId, tableName, url)
    },
    handleGen(tableId, tableName, url) {
      const tableIds = this.selectionData.map(function(row, index) {
        return row.tableId
      }).join(',')

      const tableNames = this.selectionData.map(function(row, index) {
        return row.tableName
      }).join(',')

      tableId = tableId || tableIds
      tableName = tableName || tableNames
      if (!tableName || tableName.length === 1) {
        this.$modal.msgWarning('请先选中数据项')
        return
      }

      if (!url) {
        url = '/genCode?tableId=' + tableId
      }

      this.$confirm(`确定要生成[${tableName}]表代码吗？`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'primary'
      }).then(() => {
        this.$modal.loading('正在生成代码，请稍后。。。')
        window.location.href = this.$store.state.app.server_api + `${process.env.VUE_APP_MODULE_ADMIN_API}/api/system/generator${url}`
        this.$modal.closeLoading()
      }).catch(e => { this.$modal.closeLoading() })
    },
    handleColumnEdit(tableId, tableName) {
      this.openEditDialog = true
      this.$nextTick(() => {
        this.$refs.genColumnEdit.init(tableId, tableName)
      })
    }
  }
}
</script>
